﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Core.Business.Domain.Repository;
using Moq;
using Core.Business.Domain.Entities;
using VfbSharp.Validations;

namespace ControleFinanceiro.Tests.Domain
{
    [TestClass]
    public class ContaTest{
        private Mock<IContaRepository> _contaRepositoryMock;
        private Mock<ILancamentoRepository> _lancamentoRepositoryMock;
        private ILancamentoRepository _lancamentoRepository;
        private IContaRepository _contaRepository;

        [TestInitialize]
        public void Initialize(){
            _contaRepositoryMock = new Mock<IContaRepository>();

            _contaRepositoryMock.Setup(m => m.GetAllContas())
                                .Returns(GetContas());
            _contaRepositoryMock.Setup(m => m.GetContaBy(1))
                                .Returns(GetContas().FirstOrDefault());
            _contaRepository = _contaRepositoryMock.Object;


            _lancamentoRepositoryMock = new Mock<ILancamentoRepository>();

            _lancamentoRepositoryMock.Setup(m => m.GetAtendamentos(1, 1))
                                     .Returns(GetAgendamentos());
            _lancamentoRepository = _lancamentoRepositoryMock.Object;
        }

        [TestCleanup]
        public void Cleanup(){

        }

        [TestMethod]
        public void Deve_adicionar_lancamentos_em_uma_conta() {            
            var conta = _contaRepository.GetContaBy(1);
            var favorecido = new Favorecido("Teste");
            favorecido.Id = 1;

            Lancamento lancamento = new Saque(89, "okokiikjkks", favorecido, TipoSituacao.CONSOLIDADO, DateTime.Now, new Parcela(1,1));
            //Checa se existe um agendamento do mesmo favorecido
            //var agendamentos = _lancamentoRepository.GetAtendamentos(conta.Id, favorecido.Id);
            //if (agendamentos.IsNotNull())
            //    agendamentos.ToList().ForEach(a => Console.WriteLine("Descrição: {0}, Vencimento: {1}, Valor: {2}", a.Comentario, a.Vencimento, a.Valor));
            conta.AddLancamento(lancamento);

            lancamento = new Deposito(100, "", favorecido, TipoSituacao.CONSOLIDADO, DateTime.Now.AddMonths(1), new Parcela(1, 1));
            conta.AddLancamento(lancamento);

            Assert.IsTrue(conta.Lancamentos.Count() == 2);
        }

        [TestMethod]
        public void Deve_consolidar_um_lancamento() {
            /*var lancamento = _lancamentoRepository.GetAtendamentos(1, 1).FirstOrDefault();

            var situacaoAntes = lancamento.Situacao;
            lancamento.Consolidar();
            var situacaoDepois = lancamento.Situacao;

            Assert.AreNotEqual(situacaoAntes, situacaoDepois);*/
            var conta = Conta.GetConta<Corrente>("Minha conta", "Santander");

            string ok = conta.Banco;
        }

        private List<Lancamento> GetAgendamentos() {

            var favorecido = new Favorecido("Empregada");
            favorecido.Id = 1;

            var list = new List<Lancamento>();

            Lancamento lancamento = new Saque(50, "Gastos pessoais", favorecido, TipoSituacao.ABERTO, DateTime.Now.AddMonths(1), new Parcela(1, 1));
            list.Add(lancamento);
            lancamento = new Deposito(105, "Pagamento", favorecido, TipoSituacao.ABERTO, DateTime.Now.AddDays(1), new Parcela(1, 1));
            list.Add(lancamento);
            lancamento = new Saque(20, "Pagamento", favorecido, TipoSituacao.CONSOLIDADO, DateTime.Now.AddDays(-1), new Parcela(1, 1));
            list.Add(lancamento);

            return list;
        }

        private List<Conta> GetContas() { 
            var list = new List<Conta>();

            Conta conta = new Corrente("Conta Unibanco", String.Empty);
            list.Add(conta);

            conta = new Cartao("Cartão Visa Santander", String.Empty);
            list.Add(conta);

            conta = new Cartao("Cartão Master Santander", String.Empty);
            list.Add(conta);

            conta = new Cartao("Cartão Panamericano", String.Empty);
            list.Add(conta);

            conta = new Emprestimo("Empréstimo fulano de tal", String.Empty);
            list.Add(conta);

            conta = new Emprestimo("Empréstimo sicrano", String.Empty);
            list.Add(conta);

            int i = 0;
            list.ForEach(delegate(Conta c) {
                i++;
                c.Id = i;
            });

            return list;
        }
    }
}
